package com.bestcem.xm.deliver.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bestcem.xm.common.core.exception.BusinessException;
import com.bestcem.xm.common.core.oss.enums.OssPathEnum;
import com.bestcem.xm.common.core.uitls.SignUtil;
import com.bestcem.xm.component.mybatis.service.impl.XmServiceImpl;
import com.bestcem.xm.component.security.context.SecurityContextHolder;
import com.bestcem.xm.componet.filestorage.service.StorageService;
import com.bestcem.xm.componet.redis.service.RedisService;
import com.bestcem.xm.deliver.controller.v2.param.CreateWechatMpdeliversParam;
import com.bestcem.xm.deliver.convert.DeliverConvertMapper;
import com.bestcem.xm.deliver.entity.*;
import com.bestcem.xm.deliver.enums.*;
import com.bestcem.xm.deliver.grpc.client.MemberGrpcClient;
import com.bestcem.xm.deliver.grpc.client.PushGrpcClient;
import com.bestcem.xm.deliver.grpc.client.QdesGrpcClient;
import com.bestcem.xm.deliver.grpc.client.SurveyGrpcClient;
import com.bestcem.xm.deliver.grpc.client.dto.SurveyRespondentDto;
import com.bestcem.xm.deliver.grpc.client.dto.WechatOfficialInfoDto;
import com.bestcem.xm.deliver.mapper.*;
import com.bestcem.xm.deliver.mq.dto.CreateColumnsDto;
import com.bestcem.xm.deliver.mq.dto.StatusDto;
import com.bestcem.xm.deliver.mq.dto.WechatmpDeliverMessageDto;
import com.bestcem.xm.deliver.mq.send.biz.DeliverMessageSendService;
import com.bestcem.xm.deliver.service.DeliverDeliverService;
import com.bestcem.xm.deliver.service.DeliverWechatmpDeliverService;
import com.bestcem.xm.deliver.service.ServiceSequenceService;
import com.bestcem.xm.qdes.grpc.v1.services.Project;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.bestcem.xm.deliver.enums.DeliverScenesEnum.DELIVER_SCENES_WECHATMP;
import static com.bestcem.xm.deliver.enums.DeliverStatusEnum.DELIVER_STATUS_STOP;
import static com.bestcem.xm.deliver.enums.RespondentStatusEnum.RESPONDENT_STATUS_FINISH;
import static com.bestcem.xm.deliver.enums.RespondentStatusEnum.RESPONDENT_STATUS_NOTSTART;
import static com.bestcem.xm.deliver.enums.WechatMpdeliverMpTypeEnum.WECHATMPDELIVER_MP_TTYPE_CONDITION;
import static com.bestcem.xm.deliver.grpc.v1.services.DeliverAwardUseType.DELIVER_AWARD_USE_TYPE_UNUSE;
import static com.bestcem.xm.deliver.grpc.v1.services.DeliverAwardUseType.DELIVER_AWARD_USE_TYPE_USE;
import static com.bestcem.xm.deliver.util.DeliverConstant.DELIVER_MQ_BATCH_SIZE;

/**
 * @author been
 * @description 针对表【ds_deliver_wechatmpdeliver】的数据库操作Service实现
 * @createDate 2022-11-07 13:49:47
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DeliverWechatmpDeliverServiceImpl extends XmServiceImpl<DeliverWechatmpDeliverMapper, DeliverWechatmpDeliver> implements DeliverWechatmpDeliverService {

    private @NonNull RedisService redisService;
    //private @NonNull OssService ossService;

    private @NonNull PushGrpcClient pushGrpcClient;
    private @NonNull QdesGrpcClient qdesGrpcClient;
    private @NonNull MemberGrpcClient memberGrpcClient;
    private @NonNull SurveyGrpcClient surveyGrpcClient;

    private @NonNull DeliverDeliverMapper deliverDeliverMapper;
    private @NonNull DeliverSurveyDeliverMapper deliverSurveyDeliverMapper;
    private @NonNull DeliverConvertMapper deliverConvertMapper;
    private @NonNull DeliverWechatmpDeliverMemberIdMapper wechatMpdeliverMemberIdMapper;
    private @NonNull DeliverExtDeliverMappingMapper deliverExtDeliverMappingMapper;
    private @NonNull DeliverDeliverExtParamsMapper deliverDeliverExtParamsMapper;
    private @NonNull DeliverSurveyExtParamsVersionMapper deliverSurveyExtParamsVersionMapper;
    private @NonNull DeliverWechatmpRecordMapper deliverWechatMprecordMapper;
    private @NonNull DeliverDeliverSurveyDataMapper deliverSurveyDataMapper;

    private @NonNull ServiceSequenceService serviceSequenceService;
    private @NonNull DeliverDeliverService deliverDeliverService;
    private @NonNull DeliverMessageSendService deliverMessageSendService;
    private @NonNull StorageService storageService;

    public static final String WECHATMPDELIVER_EXPORT = "wechatmpdeliver/export/";
    private static final String SEPARATOR = "/";

    @Override
    public List<WechatOfficialInfoDto> getWechatmp() {
        List<WechatOfficialInfoDto> list = pushGrpcClient.listAccountInfo(SecurityContextHolder.getOrgId());
        return list.stream().sorted(Comparator.comparing(WechatOfficialInfoDto::getAuthorizeTime, Comparator.reverseOrder())).collect(Collectors.toList());
        //return list.stream().sorted(Comparator.comparing(WechatOfficialInfoDto::getAuthorizeTime).reversed()).collect(Collectors.toList());
        //Collections.sort(list, Comparator.comparing(WechatOfficialInfoDto::getAuthorizeTime).reversed());
        //return list;
    }

    @Override
    public JSONObject getWechatTemplates(String appId) {
        List<JSONObject> retlist = pushGrpcClient.listMsgTemplates(appId, SecurityContextHolder.getOrgId()).stream().filter(tmp -> StrUtil.containsAny(tmp.getContent(), "{first.DATA}", "{remark.DATA}")).map(item -> {
            String content = item.getContent();
            JSONObject template = JSONObject.parseObject(JSONObject.toJSONString(item));
            List<String> content_content = StrUtil.split(content, "\\n");
            String first = content_content.get(0);
            String remark = content_content.get(content_content.size() - 1);

            Map<String, String> firstmap = new HashMap<>();
            firstmap.put("keyword", StrUtil.removeAll(first, StrUtil.SPACE));
            Map<String, String> remarkmap = new HashMap<>();
            remarkmap.put("keyword", StrUtil.removeAll(remark, StrUtil.SPACE));
            Map<String, Object> newtemplatecontent = new LinkedHashMap<>();
            newtemplatecontent.put("first", firstmap);
            JSONArray content_array = new JSONArray();
            content_content.subList(1, content_content.size() - 2).stream()
                    .filter(s1 -> s1.contains(":"))
                    .forEach(s2 -> {
                        String[] ts = s2.split(":");
                        Map<String, String> mp = new HashMap<>();
                        mp.put("label", StrUtil.trim(ts[0]));
                        mp.put("keyword", StrUtil.removeAll(ts[1], StrUtil.SPACE));
                        content_array.add(mp);
                    });
            newtemplatecontent.put("content", content_array);
            newtemplatecontent.put("remark", remarkmap);
            template.put("content", newtemplatecontent);
            return template;

        }).collect(Collectors.toList());
        JSONObject retobj = new JSONObject();
        retobj.put("data", retlist);
        return retobj;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONObject createWechatMpdelivers(CreateWechatMpdeliversParam param) {
        Integer is_delay = param.getIsDelay();
        LocalDateTime deliver_time = param.getDeliverTime();
        if (is_delay == 1 && Objects.isNull(deliver_time)) {
            throw new BusinessException("投放定时时间参数缺失");
        }
        Integer code = serviceSequenceService.getSequence("DELIVER", 1);
        DeliverDeliver deliver = new DeliverDeliver();
        deliver.setCode(String.valueOf(code));
        deliver.setName(param.getDeliverName());
        deliver.setOrgId(SecurityContextHolder.getOrgId());
        deliver.setCreatedId(SecurityContextHolder.getUserId());
        deliver.setTtype(DeliverTtypeEnum.DELIVER_TTYPE_WECHATMP.getValue());
        deliver.setChannel(DeliverChannelEnum.DELIVER_CHANNEL_WECHATMP.getValue());
        deliver.setScenes(DELIVER_SCENES_WECHATMP.getValue());
        deliver.setStatus(DELIVER_STATUS_STOP.getValue());
        deliver.setStarttime(LocalDateTime.now());
        deliver.setVersion(System.currentTimeMillis() * 1000);
        deliver.setDeliverTime(deliver_time);
        //默认值
        deliver.setDisable(0);
        deliver.setDelayTime("[]");
        deliver.setDelayFailedTime("{}");
        deliver.setAwardUseType(DELIVER_AWARD_USE_TYPE_UNUSE.getNumber());
        deliver.setEnableRespondent(1);
        if (StrUtil.isNotEmpty(param.getDeliverId())) {
            deliver.setId(param.getDeliverId());
        }
        deliverDeliverMapper.insert(deliver);
        param.setDeliverId(deliver.getId());

        String key = "deliver:deliver_enable_respondent" + deliver.getId();
        redisService.set(key, "1");

        DeliverSurveyDeliver surveyDeliver = new DeliverSurveyDeliver();
        surveyDeliver.setOrgId(SecurityContextHolder.getOrgId());
        surveyDeliver.setDeliverId(deliver.getId());
        surveyDeliver.setSurveyId(param.getSurveyId());
        deliverSurveyDeliverMapper.insert(surveyDeliver);

        //await redis_mq.publish(topics.project_updated, {'project_id': params.get("survey_id")})
        StatusDto dto = new StatusDto();
        dto.setProjectId(param.getSurveyId());
        deliverMessageSendService.projectUpdated(dto);

        Map<String, Object> signMap = new HashMap<>();
        signMap.put("wechatmp_subject", Optional.ofNullable(param.getWechatMpsubject()).orElse(""));
        signMap.put("wechatmp_template", Optional.ofNullable(param.getWechatMptemplate()).orElse(""));
        String hashcode = SignUtil.genSign(signMap, deliverDeliverService.getDeliverSecret());
        param.setHashCode(hashcode);

        log.info("公众号投放参数:{}", JSONUtil.toJsonStr(param));
        saveWechatMpdeliverDb(param);
        deliverDeliverService.doDefaultDeliverNameSeq(param.getDeliverName(), param.getSurveyId(), DeliverTtypeEnum.DELIVER_TTYPE_WECHATMP.getValue());
        JSONObject ret = new JSONObject();
        ret.put("id", deliver.getId());
        log.info("公众号投放创建成功");
        return ret;
    }

    private void saveWechatMpdeliverDb(CreateWechatMpdeliversParam param) {
        //deliver_wechatmpdeliver
        DeliverWechatmpDeliver mpdeliver = deliverConvertMapper.wxMpdeliverObj2Entity(param);
        mpdeliver.setOrgId(SecurityContextHolder.getOrgId());
        mpdeliver.setCreatedId(SecurityContextHolder.getUserId());
        baseMapper.insert(mpdeliver);

        //deliver_wechatmpdelivermemberid
        String wechatmpdeliver_id = mpdeliver.getId();
        List<String> memberIds = param.getMemberIdlist();
        batchInsertWechatMpdeliverMemberId(wechatmpdeliver_id, memberIds);
    }

    private void batchInsertWechatMpdeliverMemberId(String wechatmpdeliver_id, List<String> member_id_list) {
        if (!CollectionUtils.isEmpty(member_id_list)) {
            List<DeliverWechatmpDeliverMemberId> list = member_id_list.stream().map(itd -> {
                DeliverWechatmpDeliverMemberId insertobj = new DeliverWechatmpDeliverMemberId();
                insertobj.setMemberId(itd);
                insertobj.setWechatmpdeliverId(wechatmpdeliver_id);
                return insertobj;
            }).collect(Collectors.toList());

            if (!list.isEmpty()) {
                wechatMpdeliverMemberIdMapper.insertBatchSomeColumn(list);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONObject updateWechatmpdelivers(String id, JSONObject param, DeliverWechatmpDeliver wechatmp_deliver, DeliverDeliver deliver) {
        String survey_id = param.getString("survey_id");
        String deliver_id = param.getString("deliver_id");

        LambdaQueryWrapper<DeliverExtDeliverMapping> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeliverExtDeliverMapping::getSurveyId, survey_id);
        queryWrapper.eq(DeliverExtDeliverMapping::getDeliverId, deliver_id);
        queryWrapper.eq(DeliverExtDeliverMapping::getOrgId, SecurityContextHolder.getOrgId());
        queryWrapper.last("limit 1");

        DeliverExtDeliverMapping extdelivermapping = deliverExtDeliverMappingMapper.selectOne(queryWrapper);

        if (Objects.isNull(extdelivermapping)) {
            //创建ExtDeliverMapping
            DeliverExtDeliverMapping insert = new DeliverExtDeliverMapping();
            insert.setOrgId(SecurityContextHolder.getOrgId());
            insert.setSurveyId(survey_id);
            insert.setDeliverId(deliver_id);
            insert.setSystemNo(param.getString("system_no"));
            insert.setConditionNo(param.getString("condition_no"));
            deliverExtDeliverMappingMapper.insert(insert);

            //建投放外部参数表DeliverExtparams
            JSONArray ext_params = param.getJSONArray("ext_params");
            List<DeliverDeliverExtParams> extParamsList = new ArrayList<>();
            for (int i = 0; i < ext_params.size(); i++) {
                JSONObject ext_param = ext_params.getJSONObject(i);
                DeliverDeliverExtParams insertobj = new DeliverDeliverExtParams();
                //默认值
                insertobj.setStore(true);
                insertobj.setSurvey(true);

                insertobj.setOrgId(SecurityContextHolder.getOrgId());
                insertobj.setDeliverId(deliver_id);
                insertobj.setSurveyId(survey_id);
                insertobj.setDeliverExtparamType(ext_param.getInteger("deliver_extparam_type"));
                insertobj.setSource(ext_param.getInteger("source"));
                insertobj.setExtparamId(ext_param.getString("extparam_id"));
                insertobj.setExtparamName(ext_param.getString("extparam_name"));
                insertobj.setExtparamType(ext_param.getInteger("extparam_type"));
                insertobj.setRequireFlag(false);
                insertobj.setSurveyUnique(ext_param.getBoolean("survey_unique"));
                insertobj.setAesEncryptStr(ext_param.getBoolean("aes_encrypt"));
                insertobj.setStatus(ext_param.getInteger("status"));
                insertobj.setExtparamDesc(ext_param.getString("extparam_desc"));
                extParamsList.add(insertobj);
            }
            if (!CollectionUtils.isEmpty(extParamsList)) {
                deliverDeliverExtParamsMapper.insertBatchSomeColumn(extParamsList);
            }

            //await _update_or_create_surveyextparamsversion(None, survey_id)
            handleSurveyExtparamsVersion(survey_id);

            //发布消息更新答卷数据列
            //data = {
            //        "project_id": params.survey_id,
            //        "company_id": params.org_id,
            //        "deliver_id": str(deliver_id)
            //    }
            //await redis_mq.publish(topics.survey_create_columns, data)

            CreateColumnsDto dto = new CreateColumnsDto();
            dto.setProjectId(survey_id);
            dto.setCompanyId(SecurityContextHolder.getOrgId());
            dto.setDeliverId(deliver_id);
            deliverMessageSendService.surveyCreateColumns(dto);
        }
        //return SuccessData(id=await wechatmp_utils.update_wechatmpdeliver(self.session, oid, params, **kwargs))
        handleWechatMpDeliver(wechatmp_deliver, param, deliver);
        JSONObject ret = new JSONObject();
        ret.put("id", id);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONObject editWechatmpdelivers(String id, JSONObject param, DeliverWechatmpDeliver wechatmpdeliver, DeliverDeliver deliver) {
        if (wechatmpdeliver.getIsCheck().equals(0)) {
            if (wechatmpdeliver.getIsCheck().equals(1) && param.getIntValue("is_delay") == 0) {
                param.put("_sign", true);
            }
        }

        param.put("deliver_id", wechatmpdeliver.getDeliverId());
        //await origin_update_wechatmpdeliver(session, oid, params)
        originUpdateWechatMpdeliver(wechatmpdeliver, param);
        handleWechatMpDeliver(wechatmpdeliver, param, deliver);
        JSONObject ret = new JSONObject();
        ret.put("id", wechatmpdeliver.getDeliverId());
        ret.put("status", true);
        return ret;
    }

    /**
     * {"project_id":"620a003eaace70000a9fbf38","wechatmp_deliver_id":"638d85e3aace700008ab231d","member_ids":["638cd2151a6ea25a646a1aed"]}
     * {"project_id":"620a003eaace70000a9fbf38","wechatmp_deliver_id":"638d85e3aace700008ab231d","filter_params":{"status":"","survey_status":"","survey_resp_status":"","search":""},"exclude_member_ids":[]}
     *
     * @param param
     * @param response
     * @param mp_deliver
     * @param deliver
     * @author chenglong.yue <chenglong.yue@idiaoyan.com>
     * @date 2022/12/6 18:10
     */
    @Override
    public void export(JSONObject param, HttpServletResponse response, DeliverWechatmpDeliver mp_deliver, DeliverDeliver deliver) {
        if (mp_deliver.getMpTtype().equals(WECHATMPDELIVER_MP_TTYPE_CONDITION.getValue())) {
            String ossurl = exportExcelWechatmpConditionRecordByIds(param, response, mp_deliver, deliver);
            log.info("公众号投放导出文件路径={}", ossurl);
        } else {
            Integer check_submit = mp_deliver.getCheckSubmit();
            String project_id = param.getString("project_id");
            List<JSONObject> wechatmp_record_list;
            if (param.containsKey("member_ids")) {
                List<String> member_ids = param.getJSONArray("member_ids").toJavaList(String.class);
                if (CollectionUtils.isEmpty(member_ids)) {
                    throw new BusinessException("缺少联系人member_ids");
                }

                wechatmp_record_list = getWechatmpRecordBySelect(mp_deliver, project_id, member_ids);
            } else {
                List<String> exclude_member_ids = null;
                if (param.containsKey("exclude_member_ids")) {
                    exclude_member_ids = param.getJSONArray("exclude_member_ids").toJavaList(String.class);
                }

                JSONObject filter_params = param.getJSONObject("filter_params");
                wechatmp_record_list = getWechatmpRecordByFilterParams(mp_deliver, filter_params, exclude_member_ids, project_id);
            }

            //导出
            String ossurl = exportExcelWechatmpRecordByIds(wechatmp_record_list, check_submit, response);
            log.info("公众号投放导出文件路径={}", ossurl);
        }
    }


    private String exportExcelWechatmpRecordByIds(List<JSONObject> wechatmpRecordList, Integer check_submit, HttpServletResponse response) {
        if (CollectionUtils.isEmpty(wechatmpRecordList)) {
            return "没有数据";
        }
        List<List<List<String>>> head = new ArrayList<>();
        List<List<String>> headRowList = new ArrayList<>();

        List<List<List<String>>> exportDataList = new ArrayList<>();
        List<List<String>> rowList = new ArrayList<>();

        for (JSONObject wechatmp_record : wechatmpRecordList) {
            List<String> exportItem = new ArrayList<>();

            exportItem.add(wechatmp_record.getString("openid"));
            exportItem.add(wechatmp_record.getString("nickname"));
            exportItem.add(wechatmp_record.getString("username"));
            exportItem.add(wechatmp_record.getString("surveylink"));
            exportItem.add(wechatmp_record.getString("send_status"));
            exportItem.add(wechatmp_record.getString("send_time"));

            if (check_submit.equals(1)) {
                exportItem.add(RespondentStatusEnum.getDescByValue(wechatmp_record.getIntValue("survey_resp_status")));
            } else {
                exportItem.add(wechatmp_record.getString("finished"));
            }
            rowList.add(exportItem);
        }
        if (check_submit.equals(1)) {
            getTitleHead(headRowList, Stream.of("微信OpenID", "微信昵称", "姓名", "问卷链接", "发送状态", "发送时间", "答卷状态").collect(Collectors.toList()));
        } else {
            getTitleHead(headRowList, Stream.of("微信OpenID", "微信昵称", "姓名", "问卷链接", "发送状态", "发送时间", "成功完成答卷").collect(Collectors.toList()));
        }
        head.add(headRowList);
        exportDataList.add(rowList);
        // sheet页名称-自定义，如果没有则传空
        List<String> sheetNameList = Stream.of("sheet1").collect(Collectors.toList());
        String ossPath = OssPathEnum.TEMP_DELIVER.getPath() + WECHATMPDELIVER_EXPORT + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN) + SEPARATOR;
        //return ExcelExportUtil.exportWithDynamicData2("投放清单明细", head, exportDataList, sheetNameList, response, ossService, ossPath, OssPathEnum.TEMP_DELIVER);
        //return ExcelExportUtil.exportWithDynamicData2("投放清单明细", head, exportDataList, sheetNameList, response, storageService, ossPath, OssPathEnum.TEMP_DELIVER);
        return deliverDeliverService.exportWithDynamicData("投放清单明细", head, exportDataList, sheetNameList, response, ossPath);
    }

    private List<JSONObject> getWechatmpRecordByFilterParams(DeliverWechatmpDeliver wechatmp_deliver, JSONObject filter_params, List<String> exclude_member_ids, String project_id) {
        List<JSONObject> wechatmp_record_list = new ArrayList<>();
        Boolean urged = filter_params.getBoolean("urged");
        String status = filter_params.getString("status");
        String survey_status = filter_params.getString("survey_status");
        String survey_resp_status_arg = filter_params.getString("survey_resp_status");
        String search = filter_params.getString("search");
        String s_type = filter_params.getString("s_type");
        String deliver_id = wechatmp_deliver.getDeliverId();
        Integer check_submit = wechatmp_deliver.getCheckSubmit();

        //member_maps = await get_deliver_data_member(session, urged, survey_status, deliver_id)
        LambdaQueryWrapper<DeliverDeliverSurveyData> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(DeliverDeliverSurveyData::getMemberId, DeliverDeliverSurveyData::getUrgeNums, DeliverDeliverSurveyData::getSurveyNums, DeliverDeliverSurveyData::getSurveyStatus);
        queryWrapper.eq(StrUtil.isNotBlank(survey_status), DeliverDeliverSurveyData::getSurveyStatus, survey_status);
        queryWrapper.eq(StrUtil.isNotBlank(deliver_id), DeliverDeliverSurveyData::getDeliverId, deliver_id);
        if (urged != null) {
            queryWrapper.gt(urged, DeliverDeliverSurveyData::getUrgeNums, 0);
            queryWrapper.eq(!urged, DeliverDeliverSurveyData::getUrgeNums, 0);
        }
        List<DeliverDeliverSurveyData> list = deliverSurveyDataMapper.selectList(queryWrapper);

        Map<String, List<Integer>> member_map = list
                .stream()
                .collect(Collectors.toMap(DeliverDeliverSurveyData::getMemberId, e -> {
                    List<Integer> tmp = new ArrayList<>();
                    tmp.add(e.getUrgeNums());
                    tmp.add(e.getSurveyNums());
                    tmp.add(e.getSurveyStatus());
                    return tmp;
                }, (a, b) -> a));
        Set<String> member_surveydata_ids = member_map.keySet();

        List<String> member_id_list = deliverDeliverService.getDeliverMemberIdList(deliver_id, DeliverTtypeEnum.DELIVER_TTYPE_WECHATMP);
        List<String> member_ids;
        if (urged != null) {
            member_ids = new ArrayList<>(member_surveydata_ids);
        } else {
            member_ids = member_id_list;
        }
        Map<String, Integer> member_resp_maps = new HashMap<>();
        deliverDeliverService.getMemberRespMaps(project_id, survey_resp_status_arg, deliver_id, check_submit, member_resp_maps, member_ids);
        Set<String> member_resp_ids = member_resp_maps.keySet();

        LambdaQueryWrapper<DeliverWechatmpRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DeliverWechatmpRecord::getMpDeliverId, wechatmp_deliver.getId());
        wrapper.eq(StrUtil.isNotBlank(status), DeliverWechatmpRecord::getStatus, status);
        wrapper.and(StrUtil.isNotBlank(search), wrap ->
                wrap.like(DeliverWechatmpRecord::getUsername, search)
                        .or()
                        .like(DeliverWechatmpRecord::getNickname, search)
                        .or()
                        .like(DeliverWechatmpRecord::getOpenid, search)
        );

        if (urged != null || StrUtil.isNotBlank(survey_resp_status_arg)) {
            HashSet<String> set2 = new HashSet<>(member_resp_ids);
            member_ids = new ArrayList<>(org.apache.commons.collections4.CollectionUtils.intersection(member_surveydata_ids, set2));
            wrapper.in(!org.apache.commons.collections4.CollectionUtils.isEmpty(member_ids), DeliverWechatmpRecord::getMemberId, member_ids);
        }
        //uery_params['s_type'] = s_type 没有这个字段

        wrapper.orderByDesc(DeliverWechatmpRecord::getCreatedDt);
        List<DeliverWechatmpRecord> wechatmp_records = deliverWechatMprecordMapper.selectList(wrapper);

        record2JsonObject(wechatmp_record_list, check_submit, member_resp_maps, wechatmp_records);
        if (CollectionUtils.isEmpty(exclude_member_ids)) {
            return wechatmp_record_list;
        } else {
            return wechatmp_record_list.stream().filter(one -> !exclude_member_ids.contains(one.getString("member_id"))).collect(Collectors.toList());
        }
    }

    private void record2JsonObject(List<JSONObject> wechatmp_record_list, Integer check_submit, Map<String, Integer> member_resp_maps, List<DeliverWechatmpRecord> wechatmp_records) {
        ArrayList<String> wechatmp_record_member_id = new ArrayList<>();
        for (DeliverWechatmpRecord wechatmp_r : wechatmp_records) {
            String member_id = wechatmp_r.getMemberId();
            if (wechatmp_record_member_id.contains(member_id)) {
                continue;
            } else {
                wechatmp_record_member_id.add(member_id);
            }
            JSONObject item = new JSONObject();
            item.put("openid", wechatmp_r.getOpenid());
            item.put("nickname", wechatmp_r.getNickname());
            item.put("username", wechatmp_r.getUsername());
            item.put("surveylink", JSONObject.parseObject(wechatmp_r.getParams()).getString("surveylink"));
            item.put("send_status", WechatMprecordStatusEnum.getDescByValue(wechatmp_r.getStatus()));
            item.put("send_time", wechatmp_r.getCreatedDt().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
            if (check_submit.equals(0)) {
                item.put("finished", Optional.ofNullable(member_resp_maps.get(member_id)).orElse(0));
            } else {
                item.put("survey_resp_status", Optional.ofNullable(member_resp_maps.get(member_id)).orElse(RESPONDENT_STATUS_NOTSTART.getValue()));
            }

            item.put("member_id", wechatmp_r.getMemberId());
            wechatmp_record_list.add(item);
        }
    }


    private List<JSONObject> getWechatmpRecordBySelect(DeliverWechatmpDeliver mp_deliver, String project_id, List<String> member_ids) {
        List<JSONObject> wechatmp_record_list = new ArrayList<>();
        Map<String, Integer> member_resp_maps = new HashMap<>();
        Integer check_submit = mp_deliver.getCheckSubmit();
        if (check_submit.equals(0)) {
            for (String member_id : member_ids) {
                //Integer finished = surveyGrpcClient.getDeliverMemberRespTotalCount(mp_deliver.getDeliverId(), member_id, project_id);
                Integer finished = surveyGrpcClient.getDeliverRspdAmount(mp_deliver.getDeliverId(), null, null, member_id, RESPONDENT_STATUS_FINISH.getValue(), null, project_id);
                member_resp_maps.put(member_id, finished);
            }
        } else {
            for (String member_id : member_ids) {
                //Integer survey_resp_status = surveyGrpcClient.getDeliverRespStatus(mp_deliver.getDeliverId(), member_id, project_id);
                Integer survey_resp_status = surveyGrpcClient.getDeliverRspdStatus(mp_deliver.getDeliverId(), member_id, null, null, project_id);
                member_resp_maps.put(member_id, survey_resp_status);
            }
        }

        LambdaQueryWrapper<DeliverWechatmpRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(DeliverWechatmpRecord::getCreatedDt);
        queryWrapper.in(DeliverWechatmpRecord::getMemberId, member_ids);
        queryWrapper.eq(DeliverWechatmpRecord::getMpDeliverId, mp_deliver.getId());
        List<DeliverWechatmpRecord> wechatmp_records = deliverWechatMprecordMapper.selectList(queryWrapper);
        log.info("wechatmp_records-->>{}", wechatmp_records);

        record2JsonObject(wechatmp_record_list, check_submit, member_resp_maps, wechatmp_records);

        return wechatmp_record_list;
    }

    private String exportExcelWechatmpConditionRecordByIds(JSONObject param, HttpServletResponse response, DeliverWechatmpDeliver mp_deliver, DeliverDeliver deliver) {
        List<String> dlvr_rids = param.getJSONArray("dlvr_rids").toJavaList(String.class);
        List<String> exclude_dlvr_rids = param.getJSONArray("exclude_dlvr_rids").toJavaList(String.class);
        Integer check_submit = mp_deliver.getCheckSubmit();
        String project_id = param.getString("project_id");
        String deliver_id = deliver.getId();
        String mp_deliver_id = param.getString("wechatmp_deliver_id");

        List<List<List<String>>> head = new ArrayList<>();
        List<List<String>> headRowList = new ArrayList<>();

        List<List<List<String>>> exportDataList = new ArrayList<>();
        List<List<String>> rowList = new ArrayList<>();

        List<DeliverWechatmpRecord> wechatmp_record_list;
        LambdaQueryWrapper<DeliverWechatmpRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(DeliverWechatmpRecord::getCreatedDt);
        if (!CollectionUtils.isEmpty(dlvr_rids)) {
            queryWrapper.in(DeliverWechatmpRecord::getId, dlvr_rids);
        } else {
            queryWrapper.eq(DeliverWechatmpRecord::getMpDeliverId, mp_deliver_id);
        }
        wechatmp_record_list = deliverWechatMprecordMapper.selectList(queryWrapper);

        if (!CollectionUtils.isEmpty(wechatmp_record_list)) {
            for (DeliverWechatmpRecord wechatmp_record : wechatmp_record_list) {
                if (!CollectionUtils.isEmpty(exclude_dlvr_rids) && exclude_dlvr_rids.contains(wechatmp_record.getId())) {
                    continue;
                }

                List<String> exportItem = new ArrayList<>();
                exportItem.add(wechatmp_record.getOpenid());
                exportItem.add(wechatmp_record.getNickname());
                exportItem.add(JSONObject.parseObject(wechatmp_record.getParams()).getString("surveylink"));
                exportItem.add(WechatMprecordStatusEnum.getDescByValue(wechatmp_record.getStatus()));
                exportItem.add(wechatmp_record.getCreatedDt().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
                if (check_submit.equals(1)) {
                    exportItem.add(RespondentStatusEnum.getDescByValue(wechatmp_record.getRspdStatus()));
                } else {
                    JSONObject query_params = new JSONObject();
                    query_params.put("project_id", project_id);
                    query_params.put("deliver_id", deliver_id);
                    query_params.put("status", RespondentStatusEnum.RESPONDENT_STATUS_FINISH.getValue());
                    query_params.put("dlvr_rid", wechatmp_record.getId());
                    List<SurveyRespondentDto> resps = surveyGrpcClient.listRespondent(query_params);
                    exportItem.add(String.valueOf(resps.size()));
                }

                rowList.add(exportItem);
            }
            if (check_submit.equals(1)) {
                getTitleHead(headRowList, Stream.of("微信OpenID", "微信昵称", "问卷链接", "发送状态", "发送时间", "答卷状态").collect(Collectors.toList()));
            } else {
                getTitleHead(headRowList, Stream.of("微信OpenID", "微信昵称", "问卷链接", "发送状态", "发送时间", "成功完成答卷").collect(Collectors.toList()));
            }
            head.add(headRowList);
            exportDataList.add(rowList);
            // sheet页名称-自定义，如果没有则传空
            List<String> sheetNameList = Stream.of("sheet1").collect(Collectors.toList());
            String ossPath = OssPathEnum.TEMP_DELIVER.getPath() + WECHATMPDELIVER_EXPORT + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN) + SEPARATOR;
            //return ExcelExportUtil.exportWithDynamicData2("投放清单明细", head, exportDataList, sheetNameList, response, ossService, ossPath, OssPathEnum.TEMP_DELIVER);
            //return ExcelExportUtil.exportWithDynamicData2("投放清单明细", head, exportDataList, sheetNameList, response, storageService, ossPath, OssPathEnum.TEMP_DELIVER);

            //数据准备完毕,生成本地临时文件
            //File exportFile = ExcelExportUtil.exportWithDynamicData2LocalDir("投放清单明细", head, exportDataList, sheetNameList);
            ////上传到oss
            //String url = storageService.upload(exportFile, Objects.requireNonNull(exportFile).getName(), ossPath, new Dict()).getUrl();
            //ExcelExportUtil.downloadTemplate(exportFile.getPath(), "投放清单明细", ExcelExportUtil.XLSX_SUFFIX, response);
            //exportFile.delete();
            //return url;
            return deliverDeliverService.exportWithDynamicData("投放清单明细", head, exportDataList, sheetNameList, response, ossPath);
        }
        return "没有数据";
    }

    private void getTitleHead(List<List<String>> headRowList, List<String> titelList) {
        for (String title : titelList) {
            List<String> rowHead = new ArrayList<>();
            rowHead.add(title);
            headRowList.add(rowHead);
        }
    }

    private void handleSurveyExtparamsVersion(String survey_id) {
        LambdaQueryWrapper<DeliverSurveyExtParamsVersion> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeliverSurveyExtParamsVersion::getSurveyId, survey_id);
        queryWrapper.last("limit 1");
        DeliverSurveyExtParamsVersion surveyextparamsversion_data = deliverSurveyExtParamsVersionMapper.selectOne(queryWrapper);

        if (Objects.nonNull(surveyextparamsversion_data)) {
            Integer oldVersion = surveyextparamsversion_data.getVersion();
            DeliverSurveyExtParamsVersion update = new DeliverSurveyExtParamsVersion();
            update.setVersion(oldVersion + 1);
            update.setId(surveyextparamsversion_data.getId());
            deliverSurveyExtParamsVersionMapper.updateById(update);
        } else {
            DeliverSurveyExtParamsVersion insert = new DeliverSurveyExtParamsVersion();
            insert.setVersion(1);
            insert.setSurveyId(survey_id);
            deliverSurveyExtParamsVersionMapper.insert(insert);
        }
    }

    private void handleWechatMpDeliver(DeliverWechatmpDeliver wechatmp_deliver, JSONObject param, DeliverDeliver deliver) {
        JSONObject deliver_params = new JSONObject();
        param.forEach((key, value) -> {
            if (key.startsWith("_deliver_")) {
                String real_key = StrUtil.removePrefix(key, "_deliver_");
                deliver_params.put(real_key, value);
            }
        });
        if (!deliver_params.isEmpty()) {
            long version = System.currentTimeMillis() * 1000;
            deliver_params.put("version", version);
            DeliverDeliver updateDeliver = JSON.toJavaObject(deliver_params, DeliverDeliver.class);
            updateDeliver.setId(wechatmp_deliver.getDeliverId());
            deliverDeliverMapper.updateById(updateDeliver);

            deliver.setVersion(version);
        }

        List<String> not_distrub_member_list = new ArrayList<>();
        if (!param.getJSONObject("filter_params").isEmpty()) {
            if (param.containsKey("not_distrub_member")) {
                JSONArray notDistrubMembers = param.getJSONArray("not_distrub_member");
                if (!notDistrubMembers.isEmpty()) {
                    not_distrub_member_list = notDistrubMembers.stream().map(String::valueOf).collect(Collectors.toList());
                    param.put("no_disturb_member_id_list", not_distrub_member_list);
                }
            }
            JSONObject filter_params = new JSONObject();
            filter_params.putAll(param.getJSONObject("filter_params"));
            filter_params.put("not_distrub_member", not_distrub_member_list);
            filter_params.put("push_type", "wechat");
            filter_params.put("app_id", param.getString("appid"));

            Integer superRole = SecurityContextHolder.getToken().getSuperRole();
            Integer isSenior = SecurityContextHolder.getToken().getIsSenior();
            Map<String, Object> kwargs = new HashMap<>();
            kwargs.put("org_id", SecurityContextHolder.getOrgId());
            kwargs.put("user_id", SecurityContextHolder.getUserId());
            kwargs.put("super_admin", superRole == 1);
            kwargs.put("senior_admin", isSenior == 1);
            List<String> member_ids = memberGrpcClient.listMembersByFilterParam(kwargs, filter_params.toJSONString());
            param.put("member_id_list", member_ids);

            Map<String, Object> signMap = new HashMap<>();
            signMap.put("mp_template_content", Optional.ofNullable(param.getString("mp_template_content")).orElse(wechatmp_deliver.getMpTemplateContent()));
            signMap.put("mp_template_title", Optional.ofNullable(param.getString("mp_template_title")).orElse(wechatmp_deliver.getMpTemplateTitle()));
            String hashcode = SignUtil.genSign(signMap, deliverDeliverService.getDeliverSecret());
            param.put("hashcode", hashcode);

            //await wechatmp_utils.origin_update_wechatmpdeliver(session, oid, params, return_model=return_doc)
            originUpdateWechatMpdeliver(wechatmp_deliver, param);

            //python 用来控制异步任务的执行顺序，没卵用
            /*if (Objects.isNull(param.get("is_upload"))) {
                String async_key = "deliver.wechatmpdeliver." + deliver.getId();
                redisService.set(async_key, 1, 1, TimeUnit.DAYS);
            }*/

            //python法公用update_wechatmpdeliver，再修改微信投放可能有这个参数
            if (param.containsKey("_sign") && param.getBooleanValue("_sign")) {
                // 这里会不会有一级缓存？查到的不是最新？
                wechatmp_deliver = baseMapper.selectById(wechatmp_deliver.getId());
                // 批量发送, 批量创建record
                deliverWechatMpdeliver(wechatmp_deliver, param, deliver, null, null);
            }
        }
    }

    private void originUpdateWechatMpdeliver(DeliverWechatmpDeliver wechatmp_deliver, JSONObject param) {
        String wechatmpdeliver_id = wechatmp_deliver.getId();
        if (param.containsKey("member_id_list")) {
            //如果参数中有member_id_list就先把原先数据删除
            LambdaQueryWrapper<DeliverWechatmpDeliverMemberId> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DeliverWechatmpDeliverMemberId::getWechatmpdeliverId, wechatmpdeliver_id);
            wechatMpdeliverMemberIdMapper.delete(queryWrapper);
        }

        //result = await model_utils.update_wechatmpdeliver(session, ObjectId(oid), params, return_model=return_model, **kwargs)
        //deliver_wechatmpdeliver
        DeliverWechatmpDeliver mpdeliver = JSON.toJavaObject(param, DeliverWechatmpDeliver.class);
        mpdeliver.setId(wechatmpdeliver_id);
        baseMapper.updateById(mpdeliver);

        List<String> member_id_list = param.getJSONArray("member_id_list").toJavaList(String.class);
        batchInsertWechatMpdeliverMemberId(wechatmpdeliver_id, member_id_list);
    }

    /**
     * 批量投放，支持立即和延迟
     *
     * @param wechatmp_deliver 公众号投放数据
     * @param param            参数
     * @param deliver          投放主表
     * @param deliver_check    检查状态
     * @param delayDate        延迟投放日期
     * @author chenglong.yue <chenglong.yue@idiaoyan.com>
     * @date 2022/12/16 16:44
     */
    private void deliverWechatMpdeliver(DeliverWechatmpDeliver wechatmp_deliver, JSONObject param, DeliverDeliver deliver, Boolean deliver_check, Date delayDate) {
        LambdaQueryWrapper<DeliverWechatmpDeliverMemberId> qwrap = new LambdaQueryWrapper<>();
        qwrap.select(DeliverWechatmpDeliverMemberId::getMemberId);
        qwrap.eq(DeliverWechatmpDeliverMemberId::getWechatmpdeliverId, wechatmp_deliver.getId());
        List<DeliverWechatmpDeliverMemberId> objList = wechatMpdeliverMemberIdMapper.selectList(qwrap);
        if (!CollectionUtils.isEmpty(objList)) {
            List<String> ids = objList.stream()
                    .map(DeliverWechatmpDeliverMemberId::getMemberId)
                    .filter(StrUtil::isNotEmpty).distinct().collect(Collectors.toList());
            wechatmp_deliver.setMemberIdlist(ids);
        }

        //批量发送, 批量创建record
        Project project_obj = qdesGrpcClient.getProject(wechatmp_deliver.getSurveyId());
        String projectName = project_obj.getTitle();
        String paramVersion = param.getString("version");
        String deliverVersion = deliver.getVersion().toString();
        if (StrUtil.isNotBlank(paramVersion) && StrUtil.isNotBlank(deliverVersion)) {
            if (!StrUtil.equals(paramVersion, deliverVersion)) {
                throw new BusinessException("版本不一致，玩个毛");
            }
        }

        HashMap<String, String> kwargs = new HashMap<>();
        if (deliver.getAwardUseType() == DELIVER_AWARD_USE_TYPE_USE.getNumber()) {
            kwargs.put("awardId", deliver.getAwardId());
        }

        if (Objects.nonNull(deliver_check) && deliver_check) {
            boolean a = DeliverStatusEnum.getDeliverCheck1Value().stream().noneMatch(it -> Objects.equals(it, deliver.getStatus()));
            if (a) {
                throw new BusinessException("公众号投放当前投放状态错误1");
            }
        } else {
            boolean b = DeliverStatusEnum.getDeliverCheck0Value().stream().anyMatch(it -> Objects.equals(it, deliver.getStatus()));
            if (b) {
                throw new BusinessException("公众号投放当前投放状态错误2");
            }
        }

        if (param.containsKey("member_id_list")) {
            List<String> pmidlist = param.getJSONArray("member_id_list").toJavaList(String.class).stream().filter(StrUtil::isNotEmpty).distinct().collect(Collectors.toList());
            wechatmp_deliver.setMemberIdlist(pmidlist);
        } else {
            //20221215 新建投放会调用3个接口
            //post api/deliver/v2/wechatmpdelivers/ insert表
            //put api/deliver/v2/wechatmpdeliver/639ab59eaace700008f83ee6 更新模板id mp_template_id
            //post api/deliver/deliver/639ab59eaace700008f83ee4/start/?pid=638d4f0caace700008ab1b4e 发微信模板消息
            //所以会导致 第三步模板消息的mp_template_id取不到，这里需要控制一下
            //循环重试获取member_id_list 和 mp_template_id
            if (CollectionUtils.isEmpty(wechatmp_deliver.getMemberIdlist()) || StrUtil.isEmpty(wechatmp_deliver.getMpTemplateId())) {
                wechatmp_deliver = retryQueryWechatmpDeliver(wechatmp_deliver.getId());
            }
        }

        log.info("公众号投放投放的联系人的数量为:{}", wechatmp_deliver.getMemberIdlist().size());
        //免打扰联系人id从投放联系人中去除
        List<String> no_disturb_member_id_list = deliverDeliverService.getNodisturbMemberIdByDeliver(deliver.getId()).stream().distinct().collect(Collectors.toList());
        log.info("公众号投放免打扰联系人的数量为:{}", no_disturb_member_id_list.size());
        if (CollectionUtils.isEmpty(wechatmp_deliver.getMemberIdlist())) {
            log.info("公众号投放符合条件联系人的数量为0,投尼玛呢");
            return;
        }
        //改成mq消息处理
        log.info("公众号投放发送mq消息start");

        //改成mq处理,比如5000一个mq消息，这样可以几台机器一起消费，执行投放过程
        List<List<String>> memberIdlistArry = ListUtil.partition(wechatmp_deliver.getMemberIdlist(), DELIVER_MQ_BATCH_SIZE);
        log.info("公众号投放{}发送{}条mq消息,每批次{}", deliver.getId(), memberIdlistArry.size(), DELIVER_MQ_BATCH_SIZE);
        for (List<String> subMemberIdlist : memberIdlistArry) {
            WechatmpDeliverMessageDto dto = new WechatmpDeliverMessageDto();
            dto.setId(wechatmp_deliver.getId());
            dto.setOrgId(wechatmp_deliver.getOrgId());
            dto.setSurveyId(wechatmp_deliver.getSurveyId());
            dto.setDeliverId(wechatmp_deliver.getDeliverId());
            dto.setAppid(wechatmp_deliver.getAppid());
            dto.setMpTemplateId(wechatmp_deliver.getMpTemplateId());
            dto.setMpTemplateContent(wechatmp_deliver.getMpTemplateContent());
            dto.setCheckSubmit(wechatmp_deliver.getCheckSubmit());
            dto.setKwargs(kwargs);
            dto.setProjectName(projectName);
            dto.setNoDisturbMemberIdlist(no_disturb_member_id_list);
            dto.setMemberIdlist(subMemberIdlist);
            dto.setMsgTotal(memberIdlistArry.size());
            dto.setVersion(deliver.getVersion());
            //发送mq消息
            sendDeliverMsg(dto, delayDate);
        }
        log.info("公众号投放发送mq消息end");
    }

    private void sendDeliverMsg(WechatmpDeliverMessageDto dto, Date delayDate) {
        if (Objects.isNull(delayDate)) {
            //立即投放
            deliverMessageSendService.wechatmpDeliverSend(dto);
        } else {
            //延迟投放
            deliverMessageSendService.wechatmpDeliverSend(dto, delayDate);
        }
    }

    private DeliverWechatmpDeliver queryWechatmpDeliverAndMemberIdList(String id) {
        DeliverWechatmpDeliver wechatmp_deliver = baseMapper.selectById(id);
        if (StrUtil.isEmpty(wechatmp_deliver.getMpTemplateId())) {
            throw new BusinessException("公众号投放更新还没结束，稍后重试查询1");
        }

        LambdaQueryWrapper<DeliverWechatmpDeliverMemberId> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(DeliverWechatmpDeliverMemberId::getMemberId);
        wrapper.eq(DeliverWechatmpDeliverMemberId::getWechatmpdeliverId, id);
        List<DeliverWechatmpDeliverMemberId> objList = wechatMpdeliverMemberIdMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(objList)) {
            throw new BusinessException("公众号投放更新还没结束，稍后重试查询2");
        }

        List<String> ids = objList.stream()
                .map(DeliverWechatmpDeliverMemberId::getMemberId)
                .filter(StrUtil::isNotEmpty).distinct().collect(Collectors.toList());
        wechatmp_deliver.setMemberIdlist(ids);
        return wechatmp_deliver;
    }

    private DeliverWechatmpDeliver retryQueryWechatmpDeliver(String id) {
        //表示哪些异常需要重试
        //key一定要为Throwable异常的子类    Class<? extends Throwable>
        //value为true表示需要重试
        Map<Class<? extends Throwable>, Boolean> exceptionMap = new HashMap<>();
        // 1 添加异常的处理结果 true为需要重试 false为不需要重试
        exceptionMap.put(BusinessException.class, true);

        // 2 构建重试模板实例
        RetryTemplate retryTemplate = new RetryTemplate();

        // 3 设置重试回退操作策略  设置重试间隔时间
        ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
        backOffPolicy.setInitialInterval(1000);
        backOffPolicy.setMultiplier(1.5);
        backOffPolicy.setMaxInterval(60000);

        // 4 设置重试策略  设置重试次数 设置异常处理结果
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(3, exceptionMap);

        //5 重试模板添加重试策略 添加回退操作策略
        retryTemplate.setRetryPolicy(retryPolicy);
        retryTemplate.setBackOffPolicy(backOffPolicy);

        // 6 调用方法
        return retryTemplate.execute(
                // RetryCallback 重试回调方法
                retryCallback -> queryWechatmpDeliverAndMemberIdList(id),
                // RecoveryCallback 异常回调方法
                recoveryCallback -> {
                    Throwable throwable = recoveryCallback.getLastThrowable();
                    log.error("retryQueryWechatmpDeliver失败, id: {}, retryCount: {}", id, recoveryCallback.getRetryCount(), throwable);
                    throw new BusinessException("公众号投放缺少关键参数member_id_list和mp_template_id，无法执行异步任务发送消息");
                }
        );
    }

    @Override
    public void triggerDeliverStatus(DeliverDeliver deliver, String action) {
        DeliverWechatmpDeliver wechatmp_deliver = Optional.ofNullable(baseMapper.selectOne(new QueryWrapper<DeliverWechatmpDeliver>().
                        lambda().eq(DeliverWechatmpDeliver::getDeliverId, deliver.getId())))
                .orElseThrow(() -> new BusinessException(String.format("WeChatMPDeliver[deliverId=%s] not found", deliver.getId())));
        JSONObject param = new JSONObject();
        param.put("version", deliver.getVersion());
        if (StrUtil.equals("done", action) && wechatmp_deliver.getIsDelay().equals(0)) {
            //立即投放
            deliverWechatMpdeliver(wechatmp_deliver, param, deliver, true, null);
        } else if (StrUtil.equals("done", action) && wechatmp_deliver.getIsDelay().equals(1)) {
            //延迟投放
            if (LocalDateTime.now().isAfter(wechatmp_deliver.getDeliverTime())) {
                //如果已经错过定时投放的投放时间，则状态为 未投放
                deliverDeliverMapper.update(null,
                        new UpdateWrapper<DeliverDeliver>().lambda()
                                .eq(DeliverDeliver::getId, deliver.getId())
                                .set(DeliverDeliver::getStatus, DELIVER_STATUS_STOP.getValue()));
                throw new BusinessException("投放时间过期");
            }

            Date delayDate = Date.from(wechatmp_deliver.getDeliverTime().atZone(ZoneId.systemDefault()).toInstant());
            deliverWechatMpdeliver(wechatmp_deliver, param, deliver, true, delayDate);
        }
    }
}




